Skip to content

feat(storybook): expose component docs to agents via official MCP addon (#3527) - #3736

Open
chinawch007 wants to merge 2 commits into
apache:mainfrom
chinawch007:feat/storybook-mcp-3527
Open

feat(storybook): expose component docs to agents via official MCP addon (#3527)#3736
chinawch007 wants to merge 2 commits into
apache:mainfrom
chinawch007:feat/storybook-mcp-3527

Conversation

@chinawch007

Copy link
Copy Markdown
Contributor

Summary

Agents writing UI code in this repo had no machine-readable interface to
learn which components exist and how to use them, so they grepped and read
component sources to guess props and usage. This PR self-hosts Storybook's
official MCP addon at http://localhost:6006/mcp, exposing the docs
toolset only, so agents can query the existing story catalog before
writing code.

  • apps/desktop: install @storybook/addon-mcp and register it in
    .storybook/main.ts with toolsets: { dev: false, test: false, docs: true }
    (test toolset needs @storybook/addon-vitest and stays a follow-up per
    the issue)
  • new root .mcp.json registering the endpoint for agent clients
  • new root AGENTS.md: start Storybook on demand, query
    list-all-documentation / get-documentation before writing UI code,
    prefer existing packages/ui components

Fixes #3527

Verification

Manual verification succeeded against a running dev server:

  • npm --workspace @maka/desktop run storybook -- --no-open boots
    unchanged; existing stories render as before

  • MCP initialize over POST /mcp returns a session id

  • tools/list exposes exactly the three docs tools — list-all-documentation,
    get-documentation, get-documentation-for-story — confirming the
    dev/test toolsets are off:

    tool count: 3
    - list-all-documentation
    - get-documentation
    - get-documentation-for-story
    
  • all three tools return real content, e.g. get-documentation for
    primitives-toast returns the story list with usage snippets

  • npm run lint and npm run format:check pass

Not run / known gaps: full npm run build and npm test (config-only
change, no unit suite covers Storybook config); desktop-workspace
typecheck reports 40 pre-existing errors that reproduce identically on
clean main in this environment (stale workspace dists) — none touch the
changed files, which typecheck clean.

Review focus

  • .mcp.json uses the "type": "http" + "url" client convention
    (Claude Code / Cursor-class agent CLIs), not an MCP spec format; it is
    dev-time tooling config, unrelated to packages/mcp's product config.
    $schema is omitted — no official schema covers this client format.
  • .github/copilot-instructions.md (code-review guidance only) and the new
    AGENTS.md cover disjoint topics; AGENTS.md is the cross-tool
    canonical location. Mirroring into copilot-instructions.md is left as a
    maintainer decision.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: ZCode authored the config and documentation changes and
ran the verification above; the human contributor reviewed the result and
performed the final verification on a live server.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found blocking issues.

[P2] MCP addon docs-only claim is not a server boundary and the endpoint is exposed on LAN

@storybook/addon-mcp replaces options via X-MCP-Toolsets (main.ts:45). The live tools/list with a dev header changes from 3 docs tools to 4 dev tools. The storybook script does not bind to loopback, so *:6006 is reachable from 10.7.0.13:6006 without auth — an on-LAN caller can re-enable the dev toolset and obtain a filesystem existence oracle (/etc/passwd vs pathNotFound).

Fix: bind to loopback (and --exact-port) and intersect request-selected toolsets with the configured allowlist; cover with header-injection tests.

[P2] Root .mcp.json is not discovered by Codex

AGENTS.md claims the endpoint is registered, but Codex discovers via .codex/config.toml [mcp_servers], not the Claude-style root JSON. Result: Codex sees the mandatory query instruction but has no tools.

Fix: ship a real project config for each claimed client or narrow the claim; verify via actual client discovery.

Checks on d75281cb67 are test: failure (unrelated CLI EOF backoff flake, but still red — not green). Code issues are independent of CI.

简体中文存在局域网暴露与 Codex 发现失败两项阻断。

@chinawch007

Copy link
Copy Markdown
Contributor Author

Thanks — both P2s are addressed in d9671e0. Details per finding:

[P2] Toolset override + LAN exposure

  • storybook dev now runs with --host 127.0.0.1 --exact-port. Verified on a
    live server: lsof reports TCP 127.0.0.1:6006 where it previously reported
    *:6006, and the endpoint still serves the three docs tools (initialize →
    tools/list → get-documentation) over both localhost and 127.0.0.1.
  • On intersecting the header selection with a configured allowlist: agreed in
    principle, but the X-MCP-Toolsets handling lives inside
    @storybook/addon-mcp itself — getToolsets() in dist/preset.js replaces
    the configured selection wholesale whenever the header is present — so the
    intersection has to happen upstream in storybookjs/mcp. I've filed
    addon-mcp: X-MCP-Toolsets request header fully replaces the configured toolsets — config acts as a default, not an allowlist storybookjs/mcp#406. With loopback-only binding the residual audience is
    local processes, which have no need of an MCP detour to probe the
    filesystem, so the attack path you demonstrated is closed.
  • The main.ts comment now states explicitly that the toolsets config is a
    default selection, not an allowlist, so no reader mistakes it for a
    boundary. Happy to add a small source-contract test pinning the loopback
    flags on the script if you want that locked.
  • Header-injection tests would be testing the addon's behavior, which lives
    in node_modules; once upstream ships the allowlist semantics I'll revisit
    what can be asserted from this repo.

[P2] Root .mcp.json not discovered by Codex

  • Went with narrowing the claim, as suggested. AGENTS.md is now client-neutral:
    the endpoint URL is stated up front, clients that read the root .mcp.json
    discover it automatically, and other clients (Codex, Cursor) are pointed at
    a one-time registration of the same URL in their own config.
  • I did not ship per-client configs: Cursor would need a separate
    .cursor/mcp.json, and Codex only reads the user-global
    ~/.codex/config.toml, which a repo cannot provision — so per-client files
    would be unshippable or untestable from here. Can add .cursor/mcp.json on
    top if maintainers prefer explicit opt-in files per client.
  • On verification: confirmed at the protocol level (initialize / tools/list /
    tool call). For discovery I can only vouch for the agent client used to
    develop this change, whose native discovery is the root .mcp.json; I have
    no Codex or Cursor environment available, which is exactly why the claim no
    longer extends to them.

CI

The red run is the CLI-workspace EOF-backoff flake you identified. Nothing in
this PR is consumed by that workspace; re-running now.

@M4n5ter
M4n5ter force-pushed the feat/storybook-mcp-3527 branch from d9671e0 to f3427b8 Compare August 26, 2026 09:01
…on (apache#3527)

Self-host the Storybook MCP endpoint at http://localhost:6006/mcp with only
the docs toolset enabled:

- install @storybook/addon-mcp in apps/desktop and register it in
  .storybook/main.ts with dev/test toolsets off (test needs
  @storybook/addon-vitest and stays a follow-up per the issue)
- register the endpoint for agent clients in a new root .mcp.json
  ("type": "http" client convention; $schema omitted since no official
  schema covers this client config format)
- add AGENTS.md guidance to query the MCP before writing UI code in
  packages/ui or apps/desktop, preferring existing components

Verified: storybook boots unchanged, tools/list exposes exactly the three
docs tools, and list-all-documentation / get-documentation /
get-documentation-for-story return real story docs over the endpoint.

Generated-by: ZCode
…pe (apache#3527)

Review follow-up addressing the two P2s:

- storybook script now passes --host 127.0.0.1 --exact-port, so the
  unauthenticated /mcp endpoint is loopback-only. The X-MCP-Toolsets
  override itself is addon-level behavior (see getToolsets() in
  @storybook/addon-mcp) and needs an upstream fix; with loopback-only
  binding a caller already has direct local filesystem access, so the
  override grants nothing it could not do directly.
- .storybook/main.ts comment now states the toolsets config is a default
  selection, not an allowlist.
- AGENTS.md no longer claims universal .mcp.json registration: clients
  that read the root .mcp.json auto-discover the endpoint; other clients
  (Codex, Cursor) register the same URL in their own config.

Verified: lsof reports 127.0.0.1:6006 (previously *:6006); MCP initialize,
tools/list, and get-documentation still work over both localhost and
127.0.0.1; lint and format:check pass.

Generated-by: ZCode
@M4n5ter
M4n5ter force-pushed the feat/storybook-mcp-3527 branch from f3427b8 to 9289175 Compare August 26, 2026 10:01
@github-actions github-actions Bot added the effort/S Under 100 readable lines label Aug 27, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds @storybook/addon-mcp to apps/desktop/.storybook/main.ts so an agent can query component docs over MCP instead of reading source, wires .mcp.json, pins the dev server with --exact-port, and adds a root AGENTS.md.

The plumbing is clean and I want to credit that before the findings. The addon goes into apps/desktop devDependencies, lock-pinned, and I confirmed it stays out of the shipped closure: third-party-closure.mjs:98-129 defines that closure as the prod closure plus maka.rendererBundledDependencies, and the addon is in neither, so audit-shipped-dependencies.mjs and the generated THIRD_PARTY_NOTICES are unaffected and there is no NOTICE obligation. The twelve transitive packages are MIT except one ISC, all ASF Category A. There is no CI install gap either — every isStorybookPath trigger in ci-test-plan.mjs:398-415 also sets code = true, which is what gates npm ci. Telemetry is a non-issue: the addon gates on core.disableTelemetry, which main.ts already sets.

The problem is not the plumbing. It is what this installs as an authority.

P1 — the root AGENTS.md is a tracked file at a path this project deliberately keeps untracked, and it is injected into Maka's own system prompt.

Two separate reasons this cannot land as part of this PR.

First, AGENTS.md is not tracked on main, and maintainer checkouts keep a local one via .git/info/exclude. Committing a tracked root AGENTS.md will make git pull refuse in every checkout that has a local file at that path. That is not a style objection; it breaks the working tree of anyone set up the current way.

Second, and more important: WORKSPACE_INSTRUCTION_FILES in packages/runtime/src/system-prompt/workspace-instructions.ts:40 is ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md']. Maka injects the project's AGENTS.md into the system prompt. So this file is not documentation — it is behavior, for every agent run inside this repository. And what it says is "Prefer composing existing packages/ui components. Introduce a new component only when nothing existing fits", with no mention of Astryx at all. Our actual authority is DESIGN.md:186, "Use Astryx primitives as the default seam", backed by the CI-gated surface inventory. An agent that reads only the injected instruction will build a new packages/ui component where DESIGN.md requires an Astryx primitive, and the surface-inventory gate will grade the result.

Please split the AGENTS.md out of this PR. If you want project instructions for agents, that is a worthwhile change but it is its own decision, it has to reconcile with DESIGN.md rather than restate it more weakly, and it needs the untracked-file collision resolved first.

P2 — the addon injects vendor-authored instructions that claim exclusive authority over component APIs, and our catalog cannot back that claim.

@storybook/addon-mcp's preset puts STORYBOOK_MCP_INSTRUCTIONS into the MCP server's instructions field, which clients inject into the system prompt. That text says to answer questions about component props and usage from the documentation tools and never from source or type definitions, and that if something is not documented, it does not exist.

Against our tree that instruction is actively wrong. Only 5 of 32 story files declare meta.component, there is no autodocs tag anywhere, and @astryxdesign/core — the primitive layer DESIGN.md makes the default seam — has no stories at all. So: an agent needs a busy button. DESIGN.md:229 requires the Astryx isLoading prop, "always — no hand-swapped labels, icons, or disable-plus-spinner recreations". The manifest has no such component, the injected instruction says the prop does not exist, and the agent hand-rolls a disable-plus-spinner. That is precisely the drift DESIGN.md exists to prevent, now instructed.

Unlike the AGENTS.md above, this string is vendor-controlled and can change on any npm update inside ^0.7.0, so it cannot be reviewed per change. If we want this addon, the honest sequencing is to get meta.component and autodocs coverage up — and Astryx covered at all — before an instruction that says "if it is not documented, it does not exist" is true enough to inject.

Three P3s:

  • The main.ts comment says the security boundary is the dev server's loopback binding. It is not. The addon's X-MCP-Toolsets: dev header overrides the configured toolsets per request against registrations that are toolset-blind, and what actually blocks a malicious page today is that the transport is constructed with no cors option, so no Access-Control-Allow-Origin is emitted. The addon never validates Origin. Consequence is bounded — I found no fs writes in the bundle; the dev toolset's worst reach is execSync('git status --porcelain') and story-source reads the Vite dev server already serves on that port. One thing I could not verify: whether Storybook's own host check runs before the addon's /mcp route. If it does not, DNS rebinding lands same-origin and the CORS absence buys nothing. Worth checking with curl -X POST -H 'Host: evil.example' -H 'Origin: https://evil.example' -H 'X-MCP-Toolsets: dev' http://127.0.0.1:6006/mcp before merge. Please fix the comment either way — a wrong stated boundary is worse than none.
  • --exact-port turns a port collision into process.exit(-1) instead of falling forward to 6007. This project's workflow encourages multiple worktrees, and apps/desktop/tests/smoke.md:71 documents that command. A deliberate trade for the hardcoded .mcp.json URL, but say so.
  • .mcp.json is unclassified by ci-test-plan.mjs, so it falls through to unknownCode = true and forces a full run. Any future .mcp.json-only PR runs the entire suite for nothing.

Ungraded notes: the body answers "does this PR entail a change in behavior?" with No, but the addon unconditionally sets features.componentsManifest: true and Storybook applies that to builds, so CI's build-storybook now generates component manifests — and the body does not claim build-storybook was run locally. "Exposes exactly the three docs tools" holds only for the default request path; the header override is disclosed in the main.ts comment but not in the summary. Separately, .gitattributes:8-11 export-ignores /.claude as repository-local agent configuration; .mcp.json is the same category and is not export-ignored, so it would ship in the ASF source artifact — my call to make, flagging it. Finally, npm run lint is Biome only while CI runs npx knip --workspace apps/desktop separately; the addon publishes no "." export and knip's storybook plugin routes addon names through deferred resolution. I could not verify whether that resolves cleanly — please confirm the knip step passes.

Root cause: right seam, wrong authority. Extending the existing Storybook config instead of building a parallel harness is the correct instinct. But what gets installed is a second, vendor-authored source of truth about component APIs, in a repository whose authority is DESIGN.md plus Astryx primitives plus the generated surface inventory — and then a root AGENTS.md restates that authority a third time, more weakly and without Astryx. One fact, three representations, one of them written by a third party and shipped inside a caret range.

AI use: Claude Code (Opus) produced the initial findings, including unpacking @storybook/addon-mcp@0.7.0 and its transitive tree to read the actual bundles and license set. I independently re-verified the P1 — that AGENTS.md is absent from origin/main, excluded via .git/info/exclude, and listed in WORKSPACE_INSTRUCTION_FILES — and the DESIGN.md authority lines it conflicts with. The DNS-rebinding ordering question is explicitly unverified. The reviewer of record reviewed and accepted this.

简体中文

apps/desktop/.storybook/main.ts 中加入 @storybook/addon-mcp,使 agent 可以通过 MCP 查询组件文档而非读源码;同时接入 .mcp.json、用 --exact-port 固定开发服务器端口,并新增根目录 AGENTS.md

管道部分是干净的,先肯定这一点。addon 进的是 apps/desktop 的 devDependencies 并已锁定版本,我确认它不进入分发闭包:third-party-closure.mjs:98-129 把该闭包定义为生产闭包加 maka.rendererBundledDependencies,而 addon 两者都不在,因此 audit-shipped-dependencies.mjs 与生成的 THIRD_PARTY_NOTICES 不受影响,也没有 NOTICE 义务。十二个传递依赖除一个 ISC 外均为 MIT,都属 ASF Category A。CI 也没有安装缺口——ci-test-plan.mjs:398-415 中每个 isStorybookPath 触发都会同时置 code = true,而后者正是 npm ci 的门槛。遥测不是问题:addon 会检查 core.disableTelemetry,而 main.ts 已将其置为 true。

问题不在管道,而在于它安装了什么样的权威。

P1 —— 根目录 AGENTS.md 是一个被纳入版本控制的文件,而本项目刻意让该路径不受版本控制;并且它会被注入 Maka 自己的系统提示。

两个各自独立的理由使它不能作为本 PR 的一部分落地。

其一,AGENTS.mdmain 上并未被跟踪,维护者的检出通过 .git/info/exclude 保留本地副本。提交一个被跟踪的根 AGENTS.md,会让所有在该路径存在本地文件的检出 git pull 失败。这不是风格意见,而是会破坏按现有方式配置者的工作树。

其二,也更重要:packages/runtime/src/system-prompt/workspace-instructions.ts:40WORKSPACE_INSTRUCTION_FILES['AGENTS.md', 'CLAUDE.md', 'GEMINI.md']。Maka 会把项目的 AGENTS.md 注入系统提示。因此该文件不是文档,而是行为,作用于本仓库内每一次 agent 运行。而它写的是"优先组合已有的 packages/ui 组件,只有在没有现成组件合适时才引入新组件",全文未提 Astryx。我们真正的权威是 DESIGN.md:186——"Use Astryx primitives as the default seam",并有 CI 把关的 surface inventory 支撑。只读到注入指令的 agent,会在 DESIGN.md 要求使用 Astryx 原语的地方新建 packages/ui 组件,然后被 surface-inventory 闸门判定。

请把 AGENTS.md 从本 PR 拆出。若你想为 agent 提供项目指令,这是有价值的改动,但它是独立决策,需要与 DESIGN.md 调和而非更弱地复述,并且要先解决未跟踪文件的冲突。

P2 —— addon 注入了由第三方撰写、宣称对组件 API 拥有排他权威的指令,而我们的目录支撑不了该主张。

@storybook/addon-mcp 的 preset 会把 STORYBOOK_MCP_INSTRUCTIONS 放进 MCP 服务器的 instructions 字段,客户端会将其注入系统提示。该文本要求:关于组件 props 与用法的问题一律用文档工具回答,绝不依据源码或类型定义;且"若未被文档记录,它就不存在"。

对照我们的代码树,这条指令是主动错误的。32 个 story 文件中只有 5 个声明了 meta.component,全仓没有任何 autodocs 标签,而 DESIGN.md 指定为默认接缝的原语层 @astryxdesign/core 完全没有 story。于是:agent 需要一个 busy 按钮,DESIGN.md:229 要求"always"使用 Astryx 的 isLoading prop,"不得手工替换文案、图标,或用 disable 加 spinner 重造"。而清单里没有这个组件,注入的指令说该 prop 不存在,agent 于是手搓了 disable 加 spinner——这正是 DESIGN.md 要防止的漂移,如今被写成了指令。

与上面的 AGENTS.md 不同,这个字符串由第三方控制,可能在 ^0.7.0 范围内的任何一次 npm update 中改变,无法逐次评审。若我们要用这个 addon,诚实的次序是:先把 meta.component 与 autodocs 覆盖率提上去、并让 Astryx 有覆盖,再注入"未记录即不存在"这类足够为真的指令。

三条 P3:

  • main.ts 注释称安全边界是开发服务器的 loopback 绑定。并非如此。addon 的 X-MCP-Toolsets: dev 请求头可逐请求覆盖已配置的工具集,而注册本身对工具集无感知;今天真正阻挡恶意页面的,是传输层构造时未传 cors 选项,因而不会输出 Access-Control-Allow-Origin。addon 从不校验 Origin。后果是有界的——我在整个 bundle 中未发现 fs 写操作,dev 工具集最大触达是 execSync('git status --porcelain') 和 story 源码读取,而后者 Vite 开发服务器本就在同一端口提供。有一点我无法核实:Storybook 自身的 host 检查是否先于 addon 的 /mcp 路由运行。若否,DNS rebinding 将落在同源,CORS 的缺失也就毫无意义。合并前值得用 curl -X POST -H 'Host: evil.example' -H 'Origin: https://evil.example' -H 'X-MCP-Toolsets: dev' http://127.0.0.1:6006/mcp 验一下。无论结果如何请修正该注释——错误的边界声明比没有更糟。
  • --exact-port 把端口冲突从回退到 6007 变成 process.exit(-1)。本项目的工作流鼓励多 worktree,且 apps/desktop/tests/smoke.md:71 记录了该命令。作为写死 .mcp.json URL 的有意取舍可以接受,但请写明。
  • .mcp.json 未被 ci-test-plan.mjs 分类,会落到 unknownCode = true 而强制全量运行。将来任何只改 .mcp.json 的 PR 都会白跑整套测试。

未定级说明:正文对"本 PR 是否带来行为变化"回答 No,但 addon 无条件设置 features.componentsManifest: true,而 Storybook 会把它应用于构建,因此 CI 的 build-storybook 现在会生成组件清单——正文也未声明本地跑过 build-storybook。"仅暴露三个文档工具"只在默认请求路径成立;请求头覆盖在 main.ts 注释中有交代,但摘要里没有。另外 .gitattributes:8-11/.claude 标为 export-ignore,理由是仓库本地的 agent 配置;.mcp.json 属同一类别却未被 export-ignore,会进入 ASF 源码制品——这由我来定,先标出。最后,npm run lint 只有 Biome,而 CI 另外跑 npx knip --workspace apps/desktop;该 addon 未发布 "." 导出,knip 的 storybook 插件对 addon 名走延迟解析。我无法核实它能否干净解析——请确认 knip 步骤通过。

根因:接缝对,权威错。 扩展既有 Storybook 配置而非另建一套 harness,直觉是对的。但被安装进来的,是关于组件 API 的第二个、由第三方撰写的事实来源,而本仓库的权威是 DESIGN.md 加 Astryx 原语加生成的 surface inventory;随后根 AGENTS.md 又把该权威第三次复述,更弱且不提 Astryx。一个事实,三份表示,其中一份由第三方撰写并随 caret 范围分发。

@chinawch007

Copy link
Copy Markdown
Contributor Author

Thanks for the depth of this review — the "right seam, wrong authority" framing
is correct, and we independently verified the factual basis of both findings
(the WORKSPACE_INSTRUCTION_FILES injection, the addon's instructions string,
and the coverage gap; our count is 5 of 27 story files declaring
meta.component). Both P1 and P2 reduce to decisions we don't think this PR
should make unilaterally, so we're laying out the trade-offs and asking for a
maintainer call.

P1 — AGENTS.md: the issue's ask and the repo's reality are in conflict

Issue #3527 explicitly asks for usage guidance in a root AGENTS.md ("query
docs before writing frontend code"). Your two findings explain why that ask
can't be satisfied as written:

  • the path is deliberately untracked and maintainers keep local copies — a
    tracked file breaks their checkouts;
  • via WORKSPACE_INSTRUCTION_FILES the file becomes product behavior (injected
    into Maka's own system prompt), and our draft restated DESIGN.md's
    authority more weakly — packages/ui-first, no Astryx — which is exactly
    the third, weaker representation the review objects to.

So the dilemma is real: omitting the file leaves the issue's guidance ask
unmet; shipping it creates the checkout collision and installs a competing
authority. We'd rather hand the whole question to maintainers than pick a side
inside this PR: whether this PR ships the file at all, and where the guidance
should live (a tracked AGENTS.md after resolving the local-file convention,
an opt-in snippet in CONTRIBUTING, or elsewhere) — and in every case it must
be reconciled with DESIGN.md (Astryx first, then packages/ui, then new
components) rather than restate it more weakly.

One mitigating fact worth putting on the record: the core propagation the
issue wanted — agents querying the catalog before writing UI — is already
carried by the MCP registration itself. Clients that discover .mcp.json get
the addon's server instructions directing them to the docs tools. What an
AGENTS.md would additionally carry is when-to-start-Storybook and the
Astryx-first hierarchy, which is precisely the part needing the authority
reconciliation above.

P2 — the injected instructions vs. our catalog coverage

We confirmed the injected string ("Undocumented props do not exist — ... not
source or types") and that our tree can't back it. On the two in-repo paths:

Coverage first. The cost is not writing the stories — it's the judgment
and review inside them:

  • meta.component + autodocs across the existing stories is mechanical and we
    can land it quickly;
  • Astryx coverage is the real cost. @astryxdesign/core exports 100+
    components. Stories that merely render a component are cheap and worthless
    here — the catalog needs DESIGN.md-canonical usage per primitive
    (isLoading states, control heights, status vocabulary), which is
    per-component design judgment, and every file then needs human design
    review. The review queue, not generation, is the long pole. A scoped set
    covering the primitives DESIGN.md actually names (Button + isLoading,
    Badge, StatusDot, the Field family, Spinner, Skeleton, …) is ~10–15
    components and reviewable; full-library coverage is a multi-cycle effort we
    don't think should gate this PR.
  • For fairness of accounting: this coverage work stands on its own as
    Storybook hygiene (human docs, Astryx upgrade canary) — worth doing for
    those reasons regardless of this addon.

Local patch. Replacing the injected instructions with a repo-authored
string via the dependency-patch mechanism is small, testable, and does return
authority to the repo (patch mismatch also fails loudly on version bumps,
forcing re-review). The downsides: it carries a fork of vendor behavior
indefinitely — every bump re-derives the patch — and it papers over the
coverage gap rather than closing it.

The call we'd like from maintainers: (1) merge the interface with the
injected-instructions risk disclosed and coverage tracked as a follow-up;
(2) require the scoped coverage set first — we'll draft it for review;
(3) require the patch. We're ready to execute whichever is chosen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt Storybook's official MCP addon to give agents a queryable component interface

2 participants